package com.roger.springcloudGreenwich.config;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class DistributedRedisLock {

    @Autowired
    RedissonClient redissonClient;

    // 加锁
    public Boolean lock(String lockName) {
        if (null == redissonClient) {
            log.info("DistributedRedisLock redissonClient is null");
            return false;
        }

        try {
            RLock lock = redissonClient.getLock(lockName);
            // 锁10秒自动释放
            lock.lock(10, TimeUnit.SECONDS);
            log.info("Thread [{}] DistributedRedisLock lock [{}] success 上锁成功", Thread.currentThread().getName(), lockName);
            // 加锁成功
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("DistributedRedisLock lock [{}] Exception:", lockName, e);
            return false;
        }
    }

    // 释放锁
    public Boolean unlock(String lockName) {
        if (redissonClient == null) {
            log.info("DistributedRedisLock redissonClient is null");
            return false;
        }

        try {
            RLock lock = redissonClient.getLock(lockName);
            lock.unlock();
            log.info("Thread [{}] DistributedRedisLock unlock [{}] success 解锁", Thread.currentThread().getName(), lockName);
            // 释放锁成功
            return true;
        } catch (Exception e) {
            log.error("DistributedRedisLock unlock [{}] Exception:", lockName, e);
            return false;
        }
    }

    public boolean releaseLock(String lockName) {
        if (redissonClient == null) {
            log.info("DistributedRedisLock redissonClient is null");
            return false;
        }
        try {
            RLock rLock = redissonClient.getLock(lockName);
            if(rLock != null) {
                //如果锁被当前线程持有，则释放。多一个判断，减少报错信息的出现
                //在解锁之前先判断要解锁的key是否已被锁定并且是否被当前线程保持。如果满足条件时才解锁。
                if(rLock.isLocked() && rLock.isHeldByCurrentThread()) {
                    //解锁
                    rLock.unlock();
                    log.info("releaseLock end-------");
                    return true;
                }else{
                    return false;
                }
            }else{
                return false;
            }

        }catch (Exception e){
            e.printStackTrace();
            log.error("error:{}",e);
            return false;
        }

    }
}
